package com.chiyoyo.redis;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.IOException;

/**
 * @author chilei
 * @since 2023/5/29
 */
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public <K, V> RedisTemplate<K, V> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<K, V> template = new RedisTemplate<K, V>();
        template.setConnectionFactory(redisConnectionFactory);

        //key、hashKey采用String的序列化方式
        //template.setKeySerializer(new GenericToStringSerializer(Object.class));
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);

        //value、HashValue采用Jackson的序列化方式
        template.setValueSerializer(stringRedisSerializer);
        template.setHashValueSerializer(stringRedisSerializer);

        //初始化函数，使用以上设置的序列化参数
        template.afterPropertiesSet();
        //设置Redis事务一致支持，可配合@Transactional使用(需要手工关闭连接的谨慎使用)
        //template.setEnableTransactionSupport(true);
        return template;
    }

    @Value("${spring.redis.redisson.config:}")
    private String redissonConfig;
    @Value("${spring.redis.host:}")
    private String redisHost;
    @Value("${spring.redis.port:}")
    private String redisPort;
    @Value("${spring.redis.password:}")
    private String redisPassword;
    @Value("${spring.application.name:}")
    private String clientName;

    @Bean
    public RedissonClient redissonClient() throws IOException {
        Config config;

        if (redissonConfig != null && !redissonConfig.isEmpty()) {
            // 从 YAML 格式加载配置
            config = Config.fromYAML(redissonConfig);
        } else {
            // 如果 redissonConfig 为空，使用默认配置
            config = new Config();
            config.useSingleServer()
                    .setAddress("redis://" + redisHost + ":" + redisPort) // Redis 地址和端口
                    .setPassword(redisPassword) // Redis 密码
                    .setConnectionPoolSize(10) // 连接池大小
                    .setSubscriptionConnectionPoolSize(10) // 订阅连接池大小
                    .setIdleConnectionTimeout(10000) // 连接空闲超时，单位：毫秒
                    .setConnectTimeout(10000) // 连接超时，单位：毫秒
                    .setTimeout(3000) // 命令等待超时，单位：毫秒
                    .setRetryAttempts(3) // 命令失败重试次数
                    .setRetryInterval(1500) // 命令重试发送时间间隔，单位：毫秒
                    .setSubscriptionsPerConnection(5) // 单个连接最大订阅数量
                    .setClientName(clientName) // 客户端名称
                    .setConnectionMinimumIdleSize(5) // 最小空闲连接数
                    .setDnsMonitoringInterval(5000); // DNS监测时间间隔，单位：毫秒
        }

        return Redisson.create(config);
    }

}
